package fr.ajicommerce.core.service.generics;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import fr.ajicommerce.core.dao.generics.AbstractDAO;

@Transactional
public abstract class GenericService<ADTO, A> implements
		AbstractService<ADTO, A> {

	Logger log = Logger.getLogger(getClass());

	@Autowired
	protected AbstractDAO<A, Long> genericDAO;

	private Class<A> classOfA;
	private Class<ADTO> classOfADTO;

	public GenericService(Class<A> classOfA, Class<ADTO> classOfADTO) {
		super();
		this.classOfA = classOfA;
		this.classOfADTO = classOfADTO;
	}

	// logique métier ici
	@Override
	public void save(ADTO t) {

		A a = null;
		try {
			a = classOfA.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		System.out.println("Save :" + this.classOfA.getName());
		BeanUtils.copyProperties(t, a);
		genericDAO.save(a);
		BeanUtils.copyProperties(a, t);
	}
	
	@Override
	public void detach(ADTO t) {

		A a = null;
		try {
			a = classOfA.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		System.out.println("detach :" + this.classOfA.getName());
		BeanUtils.copyProperties(t, a);
		genericDAO.detach(a);
		BeanUtils.copyProperties(a, t);
	}
	

	@Override
	public void merge(ADTO t) {

		A a = null;
		try {
			a = classOfA.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		
		BeanUtils.copyProperties(t, a);
		genericDAO.merge(a);
		BeanUtils.copyProperties(a, t);
	}
		
	@Override
	public void delete(ADTO t) {
		A a = null;
		try {
			a = classOfA.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		BeanUtils.copyProperties(t, a);
		genericDAO.delete(a);

	}

	@Override
	public ADTO find(Long entityId) {
		ADTO t = null;
		try {
			t = classOfADTO.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		System.out.println("genericDAO :"+ genericDAO);
		BeanUtils.copyProperties(genericDAO.find(entityId), t);

		return t;
	}

	@Override
	public List<ADTO> findAll() {

		ADTO t = null;
		List<ADTO> listT = new ArrayList<ADTO>();

		for (A a : genericDAO.findAll()) {
			try {
				t = classOfADTO.newInstance();
			} catch (InstantiationException | IllegalAccessException e) {
				e.printStackTrace();
			}
			BeanUtils.copyProperties(a, t);
			listT.add(t);

		}

		return listT;
	}

	@Override
	public ADTO update(ADTO entity) {

		A a = null;
		try {
			a = classOfA.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		BeanUtils.copyProperties(entity, a);
		a = genericDAO.update(a);
		BeanUtils.copyProperties(a, entity);

		return entity;
	}

	@Override
	public ADTO findOneResult(String namedQuery, Map<String, Object> parameters) {

		ADTO t = null;
		try {
			t = classOfADTO.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		BeanUtils.copyProperties(
				genericDAO.findOneResult(namedQuery, parameters), t);

		return t;
	}


}
